<?php
/**
 * Created by PhpStorm.
 * User: wttfire
 * Date: 2021/3/24
 * Time: 下午1:17
 */

namespace app\api\controller;

use think\Controller;
use think\Exception;
use think\Request;

/**
 * Class ExpediaApi
 * @package app\api\controller
 * expedia 预定流程
 * 1 检索地区ID
 * 2 依据地区ID，入住日期，退房日期和入住人数 获取酒店ID集合
 * 3 依据酒店ID集合获取酒店列表【概况】
 * 4 依据酒店ID获取酒店详情和房间信息
 * 5 依据房间和预定信息进行检索房间是否符合条件
 * 6 预定符合条件的房间生成预订单
 * 7 依据预订单进行修改房间或取消预定等操作
 * 8 支付预订单 生成 服务订单
 * 9 服务订单生成通知服务，用于提升用户的入住体验
 * 10 完成服务订单，客户可进行酒店评价
 */
class ExpediaApi extends Controller
{

    private $apiUrl = 'https://test.ean.com/2.4';
    private $apiKey = '78r1ivat8d5mlb1jn13sbcm098';
    private $sharedSecret = '54rgktpkfo9tb';

    protected function authentication()
    {
        $timestamp = time();
        $Authorization = 'Authorization: EAN APIKey=' . $this->apiKey
            . ',Signature=' . hash("sha512", $this->apiKey . $this->sharedSecret . $timestamp)
            . ',timestamp=' . time();
        return $Authorization;
//        var_dump($timestamp,$Authorization);
    }

    //获取区域信息
    public function regions()
    {
        $params = ['language=zh-TW', 'include=details'];
        $url = $this->apiUrl . '/regions?' . implode('&', $params);
        $headers[] = $this->authentication();
        $result = Common::http($url, 'GET', [], $headers);
        $result = json_decode($result, true);
        return $this->result($result, 200, 'success', 'json');
        var_dump($result);
    }

    public function json2kv(Request $request)
    {
        $post = $request->post();
        foreach ($post as $k => $value) {
            if (!empty($value['key']) && !empty($value['value'])) {
                $value['value'] = $value['value'] == '/1' ? '' : $value['value'];
                echo $value['key'] . ":" . $value['value'] . "\n";
            }
        }
    }

    //通过regionId获取property_ids列表
    public function getPropertyIdsByRegion(Request $request)
    {
        if (!$request->isPost()) return $this->error('请以POST方式传播');
        $post = $request->post();

        if (empty($post['region_id'])) return $this->error('请输入地区ID');

        $reslut = (new KbxOrder())->hotelLlistByRegion($post['region_id']);
        if (!empty($reslut)) return $this->error('数据为空');
        return $this->success('success', '', $reslut);
    }

    //通过property_ids列表获取酒店列表
    public function getHotelListByPropertyIds(Request $request)
    {
        if (!$request->isPost()) return $this->error('请以POST方式传播');
        $post = $request->post();

        if (empty($post['property_ids'])) return $this->error('请输入酒店ID');

        $reslut = (new KbxOrder())->hotelLlistByRegion($post['property_ids']);

        if (!empty($reslut)) return $this->error('数据为空');
        return $this->success('success', '', $reslut);
    }

    //通过property_id获取酒店详情
    public function getHotelListByRegion(Request $request)
    {
        if (!$request->isPost()) return $this->error('请以POST方式传播');
        $post = $request->post();

        if (empty($post['property_id'])) return $this->error('请输入酒店ID');

        $reslut = (new KbxOrder())->hotelLlistByRegion($post['property_id']);

        if (!empty($reslut)) return $this->error('数据为空');
        return $this->success('success', '', $reslut);
    }

    //快速预订
    public function bookProperty(Request $request)
    {
        if (!$request->isPost()) return $this->error('请以POST方式传播');
        $post = $request->post();

        if (empty($post['property_id'])) return $this->error('请输入酒店ID');

        $reslut = (new KbxOrder())->hotelLlistByRegion($post['property_id']);

        if (!empty($reslut)) return $this->error('数据为空');
        return $this->success('success', '', $reslut);
    }

    //检索景点或酒店
    public function filterCityOrHotelByKeywords(Request $request)
    {
        if (!$request->isPost()) $this->result([], -1, '请以POST提交', 'json');
        $keywords = $request->post('keywords', '');
        if (empty($keywords)) $this->result([], -1, '缺少keywords参数', 'json');

        $result = (new KbxOrder())->findRegionsAndPropertiesByName($keywords);
        $data = empty($result['msg']) ? [['name' => '暂无数据']] : $result['msg'];
        return $this->result($data, 200, 'success', 'json');
    }

    //根据日期 房间人数 和地理位置检索匹配的酒店
    public function getHotelsByFilterHotel(Request $request)
    {
        if (!$request->isPost()) $this->result([], -1, '请以POST提交', 'json');
        $postData = $request->post();
        $filterArray = ['regionId', 'checkIn', 'checkOut', 'occupancy'];
        foreach ($filterArray as $value) {
            if (empty($postData[$value])) $this->result([], -1, '缺少' . $value . '参数', 'json');
            $$value = $postData[$value];
        }
        $params = compact('regionId', 'checkIn', 'checkOut', 'occupancy');
        $result = (new KbxOrder())->searchHotelsByRegion($params);
        $data = empty($result['msg']) ? [['name' => '暂无数据']] : $result['msg'];
        return $this->result($data, 200, 'success', 'json');
    }

    //酒店详情和房间
    public function getHotelDetails(Request $request)
    {
        if (!$request->isPost()) $this->result([], -1, '请以POST提交', 'json');
        $postData = $request->post();
        $filterArray = ['propertyId', 'checkIn', 'checkOut', 'occupancy'];
        foreach ($filterArray as $value) {
            if (empty($postData[$value])) $this->result([], -1, '缺少' . $value . '参数', 'json');
            $$value = $postData[$value];
        }

        $result = (new KbxOrder())->getHotelDetails($postData);
        $data = empty($result['msg']) ? [['name' => '暂无数据']] : $result['msg'];
        return $this->result($data, 200, 'success', 'json');
    }

    //获取酒店标签
    public function formatHotelTags($hotelInfo)
    {
        if (empty($hotelInfo)) return [];
        $tags = [];
        if (!empty($hotelInfo['brand']['name'])) $tags[] = $hotelInfo['brand']['name'];
        if (!empty($hotelInfo['category']['name'])) $tags[] = $hotelInfo['category']['name'];
        if (!empty($hotelInfo['themes'])) {
            foreach ($hotelInfo['themes'] as $theme_value) {
                $tags[] = $theme_value['name'];
            }
        }
        return $tags;
    }

    #########################################3
    //Expedia酒店的国家 城市数据
    public function getExpediaCountryData()
    {
        $countryData = [];
        //获取大洲数据
        $continents = (new KbxOrder())->listEContinents();
        $boundCountryEids = db('city')->where(['type'=>'COUNTRY'])->column('eId');
        if (!empty($continents['msg']) && is_array($continents['msg'])) {
            foreach ($continents['msg'] as $continent_k => $continent_v) {
                $pData = $this->getSimpleData(0, $continent_v);
                $country = (new KbxOrder())->listECountrys($continent_v['eId']);
                if (!empty($country['msg']) && is_array($country['msg'])) {
                    $countryList = [];
                    foreach ($country['msg'] as $country_k => $country_v) {
                        $countryOne = $this->getSimpleData($continent_v['eId'], $country_v);
//                        $countryOne['pData'] = $pData;
                        $countryOne['isBound'] = in_array($countryOne['eId'],$boundCountryEids);
                        $countryList[] = $countryOne;
                    }
                    if (!empty($country)) $countryData = array_merge($countryData, $countryList);
                }
            }
        }


        return $countryData;
    }

    public function getExpediaCountryDataV2()
    {
        $countryList = [];
        //获取大洲数据
        $countries = (new KbxOrder())->getAllECountries();
        $boundCountryEids = db('city')->where(['type'=>'COUNTRY'])->column('eId');
        if (!empty($countries['msg']) && is_array($countries['msg'])) {
            foreach ($countries['msg'] as $country_k => $country_v) {
                $countryOne = $this->getSimpleData($country_v['ancestors'][0]['id'] ?? 0, $country_v);
                $countryOne['isBound'] = in_array($countryOne['eId'],$boundCountryEids);
                $countryList[] = $countryOne ;
            }
        }
        return $countryList;
    }

    public function getExpediaPoiData(Request $request)
    {
        $eId = $request->param('eId', '');
        if (empty($eId)) return $this->error('缺少参数eId');
        $poiIds = [];
        $regions = (new KbxOrder())->listERegionByParentEId($eId);
        if (!empty($regions['msg']) && is_array($regions['msg'])) {
            foreach ($regions['msg'] as $value) {
                $poiIds = array_merge($poiIds, $value['associations']['point_of_interest'] ?? []);
            }
        }
        $poiList = [];
        if (!empty($poiIds)) {
            $poiIds = array_unique($poiIds);
            $poiList = (new KbxOrder())->listERegionByEIds($poiIds);
            $poiList = !empty($poiList['msg']) && is_array($poiList['msg']) ?
                $poiList['msg'] : [];
        }
        //获取本城市的所有景点
        $city = db('city')->where(['eId'=>$eId])->find();
        if(!empty($city)){
            $poiTables = db('poi')->where([
                'groupid'=>$city['id'],
                'eId'=>['neq',''],
            ])->column('eId');
            if(!empty($poiTables)){
                foreach ($poiList as $key=>$value){
                    $poiList[$key]['isBound'] = in_array($value['eId'],$poiTables);
                }
            }
        }
        return json([
            'code' => 0,
            'msg' => 'success',
            'count' => count($poiList),
            'data' => $poiList
        ]);
    }

    public function getSimpleData($pid = 0, $data = [])
    {
        return [
            'pid' => $pid,
            'eId' => $data['eId'],
            'name' => $data['name'],
            'nameEn' => !empty($data['nameEn']) ? $data['nameEn'] : ($data['name_full'] ?? ''),
        ];
    }
    #################################################################3
//    流程说明
//    1 检测城市是否存在
//    2 存在则绑定 不存在则检测国家是否存在关联 不存在则提示手动关联国家

    //检测是否存在名称相同的城市
    public function checkExpediaCityCompareCityTable(Request $request)
    {
        $eId = $request->param('eId', '');
        $pId = $request->param('pId', '');
        if (empty($eId) || empty($pId)) return $this->error('缺少参数eId和pId');

        $city = db('city')->where(['eId' => $eId])->find();
        //存在则不于提示
        if (!empty($city)) {
            return $this->error('已绑定城市eId');
        }

        $country = db('city')->field('id,groupid,continentid,name,eng_name')
            ->where(['eId' => $pId])->find();
        if (!empty($country)) {
            $cityList = db('city')->field('id,groupid,continentid,name,eng_name')
                ->where(['groupid' => $country['id'], 'deleted' => 0])->select();
            return $this->success('Bound Country','',
                compact('country', 'cityList'));
        }

        //提示需要手动关联国家
        $cityList = db('city')->field('id,groupid,continentid,name,eng_name')
            ->where(['type' => 'CITY', 'deleted' => 0, 'eId' => ''])
            ->select();
        $countryList = db('city')->field('id,continentid,name,eng_name')
            ->where(['type' => 'COUNTRY', 'deleted' => 0])
            ->select();
        return $this->success('Need Binding Country','',
            compact('cityList', 'countryList'));
    }

    //绑定expedia城市到定制系统
    public function bindingExpediaCityToCityTable(Request $request)
    {
//        bindType
//        1 存在国家 新增城市
//        2 存在国家 绑定城市
//        3 不存在国家 直接选中国家 新增城市
//        4 不存在国家 直接选中城市 绑定城市
        $bindType = $request->param('bindType',0);
        if(!in_array($bindType,[1,2,3,4])) return $this->error('绑定类型错误！');
        $eId = $request->param('eId'.'');
        $pId = $request->param('pId','');
        if(empty($eId) || empty($pId)) return $this->error('缺少参数eId或pId！');
        $existCity = db('city')->where(['eId'=>$eId])->find();
        if(!empty($existCity)) return $this->error('该城市已绑定了其他城市！');
        $res = false;
        switch ($bindType){
            case '1':
            case '3':
                //新增城市 将groupid设置为pId,且存入eId
                $res = $this->insertExpediaCity($eId,$pId);
                break;
            case '2':
            case '4':
                //将eId绑定到pId的城市
                $res = db('city')->where(['id'=>$pId])->update(['eId'=>$eId]);
                $res = !empty($res);
                break;
        }

        if($res===true){
            return $this->success('绑定成功');
        }else {
            return $this->error(is_string($res)?$res:'绑定失败');
        }
    }

    protected function insertExpediaCity($eId,$pId){
        //1 获取expediaCity信息
        $city = (new KbxOrder())->getERegionByEId($eId)['msg'] ?? [];
        if(empty($city) || !is_array($city)) return '未查询到相关城市';
        //2 检查是否在国家下已存在同名的城市
        if(!empty($city['nameEn'])){
            $cityTable = db('city')->where([
                'groupid'=>$pId,
                'eng_name'=>$city['nameEn'],
            ])->find();
            if(!empty($cityTable)){
                $res = db('city')->where(['id'=>$cityTable['id']])->update(['eId'=>$eId]);
                return !empty($res);
            }
        }
        //2 获取国家信息
        $country = db('city')->where(['id'=>$pId])->find();
        if(empty($country)) return '未查询到相关国家';
        try{
            //4 保存入库
            $newCityData = [
                'continentid'=>$country['continentid'],
                'groupid'=>$pId,
                'name'=>$city['name']??'',
                'eng_name'=>$city['nameEn']??'',
                'lat'=>$city['coordinates']['center_longitude']??'',
                'lng'=>$city['coordinates']['center_longitude']??'',
                'create_time'=>time(),
                'update_time'=>time(),
                'type'=>'CITY',
                'eId'=>$eId
            ];
            db('city')->insert($newCityData);
            $id = db()->getLastInsID();
            //5 通知订单系统新增城市
            //同步信息到订单系统
            $newCityData['country'] = $country['kbx_id'];
            $kbx_res = (new KbxOrder())->pushNewCityToKbx($newCityData);
            if(!empty($kbx_res['id'])){
                db('city')->where('id',$id)->update(['kbx_id'=>$kbx_res['id']]);
            }
            return true;
        }catch (Exception $e){
            return $e->getMessage();
        }

    }

    //同步expedia 和 定制库 的国家数据
    public function syncCountries()
    {
        ignore_user_abort();//关闭浏览器不影响
        set_time_limit(0);//程序运行结束才停止
        $myCountries = db('city')->field('id,name,eng_name')
            ->where(['type'=>'COUNTRY','eId'=>''])->select();
//        var_dump($myCountries);exit;
        $countries = $this->getExpediaCountryDataV2();
//        var_dump($countries);exit;
        $matchNum = 0;
        trace('定制系统国家数量：'.count($myCountries));
        trace('expedia国家数量：'.count($countries));
        foreach ($myCountries as $myCountry_k=>$myCountry_v){
            if(empty($myCountry_v['eng_name'])) continue;
            foreach ($countries as $country_k=>$country_v){
                if(empty($country_v['nameEn'])){
                    trace('expedia国家无名：'.$country_k.':'.json_encode($country_v));
                    continue;
                }
                if(strtolower($myCountry_v['eng_name']) == strtolower($country_v['nameEn'])){
                    db('city')->where(['id'=>$myCountry_v['id']])->update(['eId'=>$country_v['eId']]);
                    $matchNum ++;
                    trace('ID为'.$myCountry_v['id'].'【'.$myCountry_v['name'].'】更新成功！');
                    unset($countries[$country_k]);
                }
            }
        }
        trace('共匹配的数量为：'.$matchNum);
        return '共匹配的数量为：'.$matchNum;
    }

    public function findAncestorsCountry($city)
    {
        if(empty($city['ancestors'])) return 0;
        foreach ($city['ancestors'] as $value){
            if(!empty($value['type']) && $value['type']=='country'){
                return $value['id'];
            }
        }
        return 0;
    }

}